/*
 * @Author: 黄威
 * @Date: 2021-10-28 10:51:08
 * @LastEditors: 黄威
 * @LastEditTime: 2021-10-28 13:37:28
 * @Description: 上图插件
 */
import type { BindMap, Graphic, GraphicLayer, GraphicType } from 'types'

import { toArray } from '@/utils/coordinate'
import { Error } from '@/log'

function getDatInIdx(dat: any, idx?: number) {
    // 方法
    if (typeof dat === 'function') dat = dat(idx)

    // 数组
    if (Array.isArray(dat)) dat = dat[idx || 0] || dat[0]

    // 直接返回
    return dat
}

export default class GraphicsPlugin {
    static extends = [
        'newGraphic',
        'addGraphics',
        'removeGraphics',
        'removeGraphicsById',
        'removeAllGraphics',
    ]

    vm: BindMap
    layer: GraphicLayer

    constructor(vm: BindMap) {
        this.vm = vm
        this.layer = vm.newGraphicLayer()
    }

    // 获取一个新的插件实例，所有的Graphic对象都会在这个图层内操作
    public create() {
        return new GraphicsPlugin(this.vm)
    }

    // 新建并添加一个Graphic
    public addGraphics(
        type: GraphicType,
        data: any,
        style: any,
        opt_options: any
    ) {
        const dataArr = toArray(type, data)

        if (!Array.isArray(dataArr)) return

        const gArr = []
        for (let i = 0; i < dataArr.length; i++) {
            let g

            try {
                const dat = dataArr[i]

                g = this.vm.drawGraphic(
                    type,
                    dat,
                    getDatInIdx(style, i),
                    getDatInIdx(opt_options, i),
                    this.layer
                )
            } catch (error) {
                Error('创建graphic失败', error)
            }

            gArr.push(g)
        }

        return gArr
    }

    // 删除graphic
    public removeGraphics(graphics: Graphic | Graphic[]) {
        if (!Array.isArray(graphics)) graphics = [graphics]
        graphics.forEach(g => g.remove())
    }

    // 根据id删除graphic
    public removeGraphicsById(id: string) {
        this.layer.remove(id)
    }

    // 清空图层
    public removeAllGraphics() {
        this.layer.clear()
    }

    // 销毁图层，释放资源
    public destroy() {
        this.layer.destroy()

        delete (this as any).vm
        delete (this as any).layer
    }
}
